package com.platform.usercenter.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.platform.common.core.domain.entity.SysDept;
import com.platform.common.core.domain.entity.SysRole;
import com.platform.common.core.domain.entity.SysUser;
import com.platform.common.core.exception.ServiceException;
import com.platform.common.core.utils.DateUtils;
import com.platform.common.core.utils.StringUtils;
import com.platform.common.core.utils.poi.ExcelUtil;
import com.platform.common.core.web.controller.BaseController;
import com.platform.common.core.web.domain.AjaxResult;
import com.platform.common.core.web.page.TableDataInfo;
import com.platform.common.security.annotation.RequiresPermissions;
import com.platform.common.security.utils.SecurityUtils;
import com.platform.constants.SysUserConstants;
import com.platform.usercenter.domain.*;
import com.platform.usercenter.domain.dto.SelectOptionDTO;
import com.platform.usercenter.domain.dto.SysOrganizationPermissionDTO;
import com.platform.usercenter.domain.dto.SysRoleBindVO;
import com.platform.usercenter.domain.query.SysRoleQuery;
import com.platform.usercenter.domain.vo.SysOrganizationPermissionQuery;
import com.platform.usercenter.domain.vo.SysRoleMenuValueVO;
import com.platform.usercenter.domain.vo.SysRoleValueVO;
import com.platform.usercenter.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 角色信息
 *
 * @author
 */
@Slf4j
@RestController
@RequestMapping("/role")
public class SysRoleController extends BaseController {
    @Resource
    private ISysRoleService roleService;
    @Resource
    private ISysUserService userService;
    @Resource
    private ISysUserCommonService sysUserCommonService;
    @Resource
    private ISysDeptService deptService;
    @Resource
    private ISysRoleMenuValueService roleMenuValueService;
    @Resource
    private ISysAppSceneService sysAppSceneService;
    @Resource
    private ISysOrganizationPermissionService organizationPermissionService;

    @GetMapping("/list")
    public TableDataInfo list(SysRoleQuery roleQuery) {
        startPage();
        List<SysRole> list = roleService.selectRoleListQuery(roleQuery);
        return getDataTable(list);
    }

    @RequiresPermissions("system:role:export")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysRoleQuery roleQuery) {
        List<SysRole> list = roleService.selectRoleList(roleQuery);
        ExcelUtil<SysRole> util = new ExcelUtil<>(SysRole.class);
        util.exportExcel(response, list, "角色数据");
    }

    /**
     * 根据角色编号获取详细信息
     */
    @GetMapping(value = "/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId) {
        roleService.checkRoleDataScope(roleId);
        return success(roleService.selectRoleById(roleId));
    }

    /**
     * 新增角色
     */
    @RequiresPermissions("system:role:add")
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysRole role) {
        if (!roleService.checkRoleNameUnique(role)) {
            return error("新增角色'" + role.getRoleName() + "'失败，该组织下角色名称已存在");
        } else if (!roleService.checkRoleKeyUnique(role)) {
            return error("新增角色'" + role.getRoleName() + "'失败，该组织下角色权限已存在");
        }
        role.setCreateBy(SecurityUtils.getUsername());
        return toAjax(roleService.insertRole(role));

    }

    /**
     * 修改保存角色
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysRole role) {
        // 校验该组织下是否已存在角色
        if (!roleService.checkRoleOrgUnique(role)) {
            return error("修改角色'" + role.getRoleName() + "'失败，该组织下角色已存在");
        } else if (!roleService.checkRoleNameUnique(role)) {
            return error("修改角色'" + role.getRoleName() + "'失败，该组织下角色名称已存在");
        } else if (!roleService.checkRoleKeyUnique(role)) {
            return error("修改角色'" + role.getRoleName() + "'失败，该组织下角色权限已存在");
        }
        role.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(roleService.updateRole(role));
    }

    /**
     * 修改保存角色
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("editRoleMenu")
    public AjaxResult editRoleMenu(@Validated @RequestBody SysRole role) {
        role.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(roleService.editRoleMenu(role));
    }

    /**
     * 修改保存数据权限
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/dataScope")
    public AjaxResult dataScope(@RequestBody SysRole role) {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        return toAjax(roleService.authDataScope(role));
    }

    /**
     * 状态修改
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysRole role) {
        role.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(roleService.updateRoleStatus(role));
    }

    /**
     * 删除角色
     */
    @RequiresPermissions("system:role:remove")
    @DeleteMapping("/{roleIds}")
    public AjaxResult remove(@PathVariable Long[] roleIds) {
        return toAjax(roleService.deleteRoleByIds(roleIds));
    }

    /**
     * 获取角色选择框列表
     */
    @GetMapping("/optionselect")
    public AjaxResult optionselect() {
        return success(roleService.selectRoleAllList());
    }

    /**
     * 查询已分配用户角色列表
     */
    @GetMapping("/authUser/allocatedList")
    public TableDataInfo allocatedList(SysUser user) {
        startPage();
        List<SysUser> list = userService.selectAllocatedList(user);
        return getDataTable(list);
    }

    /**
     * 查询未分配用户角色列表
     */
    @GetMapping("/authUser/unallocatedList")
    public TableDataInfo unallocatedList(SysUser user) {
        startPage();
        List<SysUser> list = userService.selectUnallocatedList(user);
        return getDataTable(list);
    }

    /**
     * 取消授权用户
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/authUser/cancel")
    public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) {
        return toAjax(roleService.deleteAuthUser(userRole));
    }

    /**
     * 批量取消授权用户
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/authUser/cancelAll")
    public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) {
        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
    }

    /**
     * 批量选择用户授权
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/authUser/selectAll")
    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) {
        roleService.checkRoleDataScope(roleId);
        return toAjax(roleService.insertAuthUsers(roleId, userIds));
    }

    /**
     * 获取对应角色部门树列表
     */
    @GetMapping(value = "/deptTree/{roleId}")
    public AjaxResult deptTree(@PathVariable("roleId") Long roleId) {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
        ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
        return ajax;
    }


    /***
     *  角色 id 获取角色信息
     * @param roleId
     * @return
     */
    @GetMapping("/getRoleById/{roleId}")
    public AjaxResult getRoleById(@PathVariable Long roleId) {
        return AjaxResult.success(roleService.selectRoleById(roleId));
    }

    //--------------------------------------------角色接口改造-------------------------------------------------//

    /**
     * 查询用户组织下的角色关系列表（标准接口）
     *
     * @return
     */
    @GetMapping("/getOrganizationalRole")
    public AjaxResult getOrganizationalRole(SysRoleQuery sysRoleQuery) {
        // 超管可以看见全部角色--判断是否为超管用户
        Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
        if (ObjectUtil.isEmpty(sysRoleQuery.getRoleId())) {
            sysRoleQuery.setUserId(null);
            if (!sysUserCommonService.isAdmin(userId)) {
                // 获取当前用户组织
                Long orgId = SecurityUtils.getLoginUser().getOrgId();
                sysRoleQuery.setOrgId(orgId);
                sysRoleQuery.setIsAdmin(SysUserConstants.N);
            }
        }
        return AjaxResult.success(roleService.selectRoleList(sysRoleQuery));
    }


    /**
     * 角色管理-数据权限配置查询
     */
    @PostMapping("getRolePerm")
    public AjaxResult getRolePerm(@RequestParam("roleId") Long roleId, @RequestParam("orgId") Long orgId) {
        List<SysRoleMenuValueVO> roleMenuValueVOS = new ArrayList<>();

        // 根据组织查询绑定应用的数据
        Map<Long, List<SysOrganizationPermissionDTO>> orgPermMap = new HashMap<>();

        // 赛选当前角色已绑定的全部菜单的应用id
        SysRoleQuery roleQuery = new SysRoleQuery();
        roleQuery.setOrgId(orgId);
        roleQuery.setRoleId(roleId);
        List<SysMenu> menus = roleService.selectAppIdByRole(roleQuery);
        if (CollectionUtil.isEmpty(menus)) {
            return AjaxResult.success(roleMenuValueVOS);
        }
        SysOrganizationPermissionQuery orgPermission = new SysOrganizationPermissionQuery();
        orgPermission.setOrgId(orgId);
        orgPermission.setIsDelete(SysUserConstants.N);
        orgPermission.setAppSceneIds(menus.stream().map(SysMenu::getAppSceneId).collect(Collectors.toList()));
        List<SysOrganizationPermissionDTO> orgPermissions = organizationPermissionService.selectSysOrganizationPermissionDTOList(orgPermission);
        if (CollectionUtil.isEmpty(orgPermissions)) {
            return AjaxResult.success(roleMenuValueVOS);
        } else {
            orgPermMap = orgPermissions.stream().collect(Collectors.groupingBy(item -> item.getAppSceneId()));
        }
        SysRoleMenuValue query = new SysRoleMenuValue();
        query.setRoleId(roleId);
        query.setIsDelete(SysUserConstants.N);
        List<SysRoleValueVO> roleValueVOList = new ArrayList<>();
        List<SysRoleMenuValue> roleMenuValueList = roleMenuValueService.selectSysRoleMenuValueList(query);
        if (CollectionUtil.isNotEmpty(roleMenuValueList)) {
            Map<String, SysRoleValueVO> sysRoleValueVOMap = new HashMap<>();
            // 处理value值
            for (SysRoleMenuValue value : roleMenuValueList) {
                try {
                    SysRoleValueVO sysRoleValueVO = new SysRoleValueVO();
                    BeanUtils.copyProperties(value, sysRoleValueVO);
                    JSONArray jsonArray = JSONObject.parseArray(sysRoleValueVO.getValue());
                    if (ObjectUtil.isNotEmpty(jsonArray)) {
                        List<SelectOptionDTO> optionDTOS = jsonArray.toJavaList(SelectOptionDTO.class);
                        sysRoleValueVO.setValusList(optionDTOS);
                    }
                    roleValueVOList.add(sysRoleValueVO);

                    sysRoleValueVOMap.put(value.getAppSceneId() + value.getCode(), sysRoleValueVO);

                } catch (Exception e) {
                    throw new ServiceException(value.getCode() + "解析value值异常:" + e.getMessage());
                }
            }
            // 根据应用id分组
            for (Long key : orgPermMap.keySet()) {

                SysRoleMenuValueVO menuValueVO = new SysRoleMenuValueVO();
                SysAppScene scene = sysAppSceneService.selectSysAppSceneByPath(key);
                menuValueVO.setName(scene.getLevelSceneName());
                List<SysRoleValueVO> sysRoleValueVOList = new ArrayList<>();
                List<SysOrganizationPermissionDTO> organizationPermissionList = orgPermMap.get(key);
                for (SysOrganizationPermissionDTO permission : organizationPermissionList) {

                    SysRoleValueVO roleValueVO = sysRoleValueVOMap.get(key + permission.getCode());
                    if (ObjectUtil.isNotEmpty(roleValueVO)) {
                        roleValueVO.setIsMust(permission.getIsMust());
                        sysRoleValueVOList.add(roleValueVO);
                    } else {
                        SysRoleValueVO sysRoleValueVO = new SysRoleValueVO();
                        sysRoleValueVO.setIsMust(permission.getIsMust());
                        sysRoleValueVO.setCode(permission.getCode());
                        sysRoleValueVO.setPermissionId(permission.getPermissionId());
                        sysRoleValueVO.setRoleId(roleId);
                        sysRoleValueVO.setOrgId(orgId);
                        sysRoleValueVO.setAppSceneId(permission.getAppSceneId());
                        sysRoleValueVOList.add(sysRoleValueVO);
                    }
                }
                menuValueVO.setRoleMenuValueList(sysRoleValueVOList);
                roleMenuValueVOS.add(menuValueVO);
            }
        } else {
            for (Long key : orgPermMap.keySet()) {
                SysRoleMenuValueVO menuValueVO = new SysRoleMenuValueVO();
                SysAppScene scene = sysAppSceneService.selectSysAppSceneByPath(key);
                menuValueVO.setName(scene.getLevelSceneName());
                List<SysRoleValueVO> sysRoleValueVOList = new ArrayList<>();
                List<SysOrganizationPermissionDTO> organizationPermissionList = orgPermMap.get(key);
                for (SysOrganizationPermissionDTO permission : organizationPermissionList) {
                    SysRoleValueVO roleValueVO = new SysRoleValueVO();
                    roleValueVO.setIsMust(permission.getIsMust());
                    roleValueVO.setCode(permission.getCode());
                    roleValueVO.setPermissionId(permission.getPermissionId());
                    roleValueVO.setRoleId(roleId);
                    roleValueVO.setOrgId(orgId);
                    roleValueVO.setAppSceneId(permission.getAppSceneId());
                    sysRoleValueVOList.add(roleValueVO);
                }
                menuValueVO.setRoleMenuValueList(sysRoleValueVOList);

                roleMenuValueVOS.add(menuValueVO);
            }
        }
        return AjaxResult.success(roleMenuValueVOS);
    }

    /**
     * 角色管理-权限分配-数据权限保存
     */
    @PostMapping("/bindRolePerm")
    public AjaxResult bindRolePerm(@RequestParam(value = "roleId") Long roleId, @RequestParam(value = "orgId") Long orgId, @RequestBody List<SysRoleValueVO> roleValues) {
        if (ObjectUtil.isEmpty(roleId)) {
            return AjaxResult.error("角色信息缺失！");
        }
        // 删除全部权限
        roleMenuValueService.deleteSysRoleMenuValueByRoleId(roleId);
        for (SysRoleValueVO menuValue : roleValues) {
            menuValue.setRoleId(roleId);
            menuValue.setOrgId(orgId);
            menuValue.setCreateBy(SecurityUtils.getUsername());
            menuValue.setCreateTime(DateUtils.getNowDate());
            if (CollectionUtil.isNotEmpty(menuValue.getValusList())) {
                menuValue.setValue(JSON.toJSONString(menuValue.getValusList()));
                roleMenuValueService.insertSysRoleMenuValue(menuValue);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 角色管理-数据权限分配下拉值
     */
    @PostMapping("/getValueByKey")
    public AjaxResult getValueByKey(@RequestParam(value = "orgId") Long orgId, @RequestParam(value = "appSceneId") Long appSceneId, @RequestParam(value = "key") String key) {

        if (ObjectUtil.isEmpty(orgId) || ObjectUtil.isEmpty(appSceneId)) {
            return AjaxResult.error("组织id或应用id缺失！");
        }
        if (StringUtils.isEmpty(key)) {
            return AjaxResult.error("编码key缺失！");
        }

        List<SelectOptionDTO> selectOptionDTOS = new ArrayList<>();

        SysOrganizationPermission permission = new SysOrganizationPermission();
        permission.setOrgId(orgId);
        permission.setAppSceneId(appSceneId);
        permission.setCode(key);
        permission.setIsDelete(SysUserConstants.N);
        List<SysOrganizationPermission> organizationPermissions = organizationPermissionService.selectSysOrganizationPermissionList(permission);
        if (CollectionUtil.isNotEmpty(organizationPermissions)) {
            for (SysOrganizationPermission value : organizationPermissions) {
                if (StringUtils.isNotEmpty(value.getValue())) {
                    try {
                        JSONArray jsonArray = JSONObject.parseArray(value.getValue());
                        if (ObjectUtil.isNotEmpty(jsonArray)) {
                            List<SelectOptionDTO> optionDTOS = jsonArray.toJavaList(SelectOptionDTO.class);
                            if (CollectionUtil.isNotEmpty(optionDTOS)) {
                                selectOptionDTOS.addAll(optionDTOS);
                            }
                        }
                    } catch (Exception e) {
                        log.error("解析JSON数据异常{}", e.getMessage());

                    }
                }
            }
        }
        return AjaxResult.success(selectOptionDTOS);
    }

    /**
     * 分配用户-新增用户的列表查询
     */
    @GetMapping("/getUserList")
    public TableDataInfo getUserList(com.platform.usercenter.domain.vo.SysRoleVO roleQuery) {
        startPage();
        return getDataTable(roleService.getRoleUserList(roleQuery));
    }

    /**
     * 分配用户-列表查询
     */
    @GetMapping("/getRoleUserList")
    public TableDataInfo getRoleUserList(com.platform.usercenter.domain.vo.SysRoleVO roleQuery) {
        startPage();
        return getDataTable(roleService.getUserList(roleQuery));
    }


    /**
     * 分配用户-批量添加用户
     */
    @PostMapping("/bindUserRole")
    public AjaxResult bindUserRole(@RequestBody SysRoleBindVO vo) {
        if (ObjectUtil.isEmpty(vo)) {
            return AjaxResult.error("参数缺失！");
        }
        roleService.bindUserRole(vo);
        return AjaxResult.success();

    }


    /**
     * 分配用户-批量取消授权
     */
    @PostMapping("/cancelUserRole")
    public AjaxResult cancelUserRole(@RequestBody SysRoleBindVO dto) {
        return AjaxResult.success(roleService.cancelUserRole(dto));
    }


}
